﻿<?php
class DatabaseObject_User extends DatabaseObject {
	static public $usertypes = array('member' => 'Member', 
	                                 'administrator' => 'Administrator');
	private $_newPassword;
	public $profile = null;

	public function __construct($db) {
		parent::__construct($db, 'users', 'userid');
		
		$this->add('username');
		$this->add('password');
		$this->add('email', '');
		$this->add('usertype', 'member');
		$this->add('groupid', 0);
		$this->add('invisible', 0);
		$this->add('regtime', 0);
		$this->add('lastlogin', 0);
		
		$this->profile = new Profile_User($db);
	}
	
	protected function preInsert() {
		return true;
	}
	
	protected function postLoad() {
		$this->profile->setUserId($this->getId());
		$this->profile->load();
	}
	
	protected function postInsert() {
		$this->profile->setUserId($this->getId());
		$this->profile->save(false);
		//$this->sendEmail('user-regiser.tpl');
		
		$space = new DatabaseObject_Space($this->_db);
		$space->userid = $this->getId();
        $space->save();
		return true;
	}
	
	protected function postUpdate() {
		$this->profile->save(false);
		return true;
	}
	
	protected function preDelete() {
		$this->profile->delete();
		$space = new DatabaseObject_Space($this->_db);
		if ($space->load($this->getId())) {
			$this->delete();
		}
		return true;
	}
	public function __set($name, $value) {
		switch ($name) {
			case 'password':
				$value = md5($value);
				break;
			case 'usertype':
				if(!array_key_exists($value, self::$usertype)) {
					$value = 0;
				}
				break;
		}
		return parent::__set($name, $value);
	}
	
	public function userNameExists($username) {
		$query = sprintf('select count(*) from %s where username = ?'
			, $this->_table);
		$result = $this->_db->fetchOne($query, $username);
		return $result['num'] > 0;
	}
	
	public function sendEmail($tpl) {
		$templater = new Templater();
		$templater->user = $this;
		
		$body = $templater->render('email/'.$tpl);
		list($subject, $body) = preg_split('/\r|\n/', $body, 2);
		
		$logger = Zend_Registry::get('logger');
		$logger->debug($subject);
		$logger->debug($body);
		
		$mail = new Zend_Mail();
		$mail->addTo($this->email, trim($this->username));
		$mail->setFrom(Zend_Registry::get('config')->email->from->email);
		$mail->setFrom(Zend_Registry::get('config')->email->from->name);
		$mail->setSubject(trim($subject));
		$mail->setBodyText(trim($body));
		$mail->send();
	}
	
	public function loginSuccess() {
		$this->lastlogin = time();
		unset($this->profile->newpassword);
		unset($this->profile->newpassword_ts);
		unset($this->profile->newpassword_key);
		
		$this->save();
		//TODO 登录成功，记录相关信息
//		$message = sprintf('成功登陆->IP:%s,USERNAME:%s', $__SERVER['REMOTE_ADDR'],
//			$this->username);
//		$logger = Zend_Registry::get('logger');
//		$logger->notice($message);
	}
	
	public function loadByUsername($username) {
		$username = trim($username);
		if (strlen($username) == 0) {
			return false;
		}
			
		$query = sprintf('select %s from %s where username = ?', 
		     join(',', $this->getSelectFields()),$this->_table);
		$query = $this->_db->quoteInto($query, $username);
		
		return $this->_load($query);
	}
	
	public function fetchPassword() {
		if(!$this->isSaved()) {
			return false;
		}
		
		$creater = new TextPassword();
		$this->_newPassword = $creater->generate();
		$this->profile->newpassword = md5($this->_newPassword);
		$this->profile->newpassword_ts = time();
		$this->profile->newpassword_key = md5(uniqid().$this->getId()
			.$this->_newPassword);
		$this->profile->save();
		//$this->sendEmail('user-fetch-password.tpl');
		
		return true;
	}
	
    public function createAuthIdentity() {
        $identity = new stdClass;
        $identity->userid = $this->getId();
        $identity->username = $this->username;
        $identity->usertype = $this->usertype;
        $identity->email = $this->email;
        $identity->lastlogin = date('Y/m/d H:i', $this->lastlogin);
        $identity->regtime = date('Y/m/d H:i', $this->regtime);
        
        $identity->resideprovince = $this->profile->resideprovince;
        $identity->birthprovince = $this->profile->birthprovince;
        $identity->residecity = $this->profile->residecity;
        $identity->birthmonth = $this->profile->birthmonth;
        $identity->birthyear = $this->profile->birthyear;
        $identity->birthcity = $this->profile->birthcity;
        $identity->birthday = $this->profile->birthday;
        $identity->authstr = $this->profile->authstr;
        $identity->gender = $this->profile->gender;
        $identity->status = $this->profile->status;
        $identity->credit = $this->profile->credit;
        $identity->alipy = $this->profile->alipy;
        $identity->blood = $this->profile->blood;
        $identity->marry = $this->profile->marry;
        $identity->nick   = $this->profile->nick;
        $identity->site   = $this->profile->site;
        $identity->msn = $this->profile->msn;
        $identity->qq = $this->profile->qq;
        
        return $identity;
    }
	
	public function comfirmNewPassword($key) {
		if (!isset($this->profile->newpassword) || 
			!isset($this->profile->newpassword_ts) ||
			!isset($this->profile->newpassword_key)) {
			return false;
		}
		
		if(time() - $this->profile->newpassword_ts > 86400) {
			return false;
		}
		
		if ($this->profile->newpassword_key != $key) {
			return false;
		}
		
		parent::__set('password', $this->profile->newpassword);
		
		unset($this->profile->newpassword);
		unset($this->profile->newpassword_ts);
		unset($this->profile->newpassword_key);
		
		return $this->save();
	}
	
	public function addToCircle($circleid) {
	}
	static public function LoginFailure($username, $code='') {
		switch ($code) {
			case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
				$reason = '用户名未定义';
				break;
			case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
				$reason = '多个用户使用此用户名';
				break;
			case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
				$reason = '密码错误';
				break;
			default :
				$reason = '发生未知错误';
		}
		//TODO 登录失败，记录相关信息
//		$message = sprintf('登陆失败->IP:%s,USERNAME:%s', $__SERVER['REMOTE_ADDR'],
//			$username);
//		
//		if (strlen($reason) > 0) {
//			$message .= sprintf('(%s)',$reason);
//		}
//		
//		$logger = Zend_Registry::get('logger');
//		$logger->notice($message);
		return $reason;
		
	}
	static public function IsValidUserName($username) {
		$validator = new Zend_Validate_Alnum();
		return $validator->isValid($username);
	}
	
    static public function GetCircles($db, $userid) {
    	//TODO 多表查询构建失败
    	/*
    	$select = $db->select();
    	$tmp = $db->select();
    	$tmp->from(array('cu' => 'circle_user'), 'cu.circleid')
    	    ->joinInner(array('u' => 'users'), 'cu.userid = u.userid', array())
    	    ->where('u.userid = ?', $userid);
    	    
    	$select->from(array('c' => 'circles'), '*')
    	       ->where('c.circleid = IN ?', $tmp);
    	
    	if (isset($title)) {
    		$select->where('c.title = ?', $title);
    	}
    	*/
    	$query = sprintf('select * from circles as c where c.circleid IN (
    	                       select circleid from circle_user as cu, users as u 
    	                           where cu.userid=u.userid and u.userid=(?))');
    	
    	$query = $db->quoteInto($query, $userid);
    	$data = $db->fetchAll($query);
    	$circles = DatabaseObject_Circle::BuildMultiple($db, 
    	   'DatabaseObject_Circle', $data);
    	
    	return $circles;
    }
    
    static public function GetCircleCount($db, $userid) {
    	$query = sprintf('select count(*) from circles as c where c.circleid IN (
                               select circleid from circle_user as cu, users as u 
                                   where cu.userid=u.userid and u.userid=(?))');
        $query = $db->quoteInto($query, $userid);
    	
        $count = $db->fetchOne($query);
        
        return $count;
    }
    
    static public function GetFriends($db, $userid, $status = 0) {
    	$tmp = sprintf('select friendid from user_friend as uf 
    	       where userid=(?) and status=(%d)', $status);
        $query = sprintf('select * from users as u
               where userid in (%s)', $tmp);
        $query = $db->quoteInto($query, $userid);
        $friend = $db->fetchAll($query);
        
        if ($status == 1) {
        	$tmp = sprintf('select userid from user_friend as uf
        	   where friendid=(?) and status=(%d)', $status);
        	$query = sprintf('select * from users as u 
        	   where userid in (%s)', $tmp);
        	$query = $db->quoteInto($query, $userid);
        	$ftmp = $db->fetchAll($query);
        	$friend = array_merge($friend, $ftmp);
        }
        
        return $friend;
    }
    
    static public function GetFriendRequest($db, $userid) {
    	$tmp = sprintf('select userid from user_friend as uf 
               where friendid=(?) and status=(%d)', 0);
        $query = sprintf('select * from users as u
               where userid in (%s)', $tmp);
        
        $query = $db->quoteInto($query, $userid);
        $friend = $db->fetchAll($query);
        
        return $friend;
    }
    public function addFriend($friendid) {
    	$table = 'user_friend';
    	$row = array('userid' => $this->getId(),
    	             'friendid' => $friendid,
    	             'dateline' => time(),
    	             'status'   => 0);
    	
    	$affect = $this->_db->insert($table, $row);
    	return ($affect == 1) ? true : false;
    }
    
    public function delFriend($friendid) {
    	$table = 'user_friend';
    	$where = sprintf('userid=(%d) and friendid=(%d)', $this->getId(), $friendid);
    	
    	$affect = $this->_db->delete($table, $where);
    	
    	return ($affect == 1) ? true : false;
    }
    
    public function statusFriend($friendid) {
    	$set = array('status' => 1);
    	$table = 'user_friend';
    	$where = sprintf('userid=(%d) and friendid=(%d)', $friendid, $this->getId());
    	
    	$affect = $this->_db->update($table, $set, $where);
    	
    	return ($affect == 1) ? true : false;
    }
//    
//    public static function GetUsers($db, $options = array()) {
//    	$defaults = array('offset' => 0,
//    	                  'limit'  => 0,
//    	                  'order'  => 'u.username'
//        );
//        
//        foreach ($defaults as $k => $v) {
//        	$options[$k] = array_key_exists($k, $options) ? $options[$k] : $v;
//        }
//
//        $select = self::_GetBaseQuery($db, $options);
//
//        $select->from(null, 'u.*');
//
//        if ($options['limit'] > 0) {
//        	$select->limit($options['limit'], $options['offset']);
//        }
//        
//        $select->order($options['order']);
//
//        $data = $db->fetchAll($select);
//
//        $users = parent::BuildMultiple($db, __CLASS__, $data);
//
//        if (count($users) == 0) {
//        	return $users;
//        }
//
//        $userids = array_keys($users);
//
//        $profiles = Profile::BuildMultiple($db,
//                                           'usersprofile',
//                                           array('userid' => $userids));
//
//        foreach ($users as $userid => $user) {
//        	if (array_key_exists($userid, $profiles)
//        	   && $profiles[$userid] instanceof Profile_User) {
//        	   	   $users[$userid]->profile = $profiles[$userid];
//        	} else {
//        		$users[$userid]->profile->setUserId($userid);
//        	}
//        }
//        return $users;
//    }
//
//    public static function GetUsersCount($db, $options) {
//    	$select = self::_GetBaseQuery($db, $options);
//    	$select->from(null, 'count(*)');
//    	return $db->fetchOne($select);
//    }
//
//    private static function _GetBaseQuery($db, $options) {
//    	$defaults = array('userid' => array());
//    	
//    	foreach ($defaults as $k => $v) {
//    		$options[$k] = array_key_exists($k, $options) ? $options[$k] : $v;
//    	}
//    	$select = $db->select();
//    	$select->from(array('u' => 'users'), array());
//    	if (count($options['userid']) > 0) {
//    		$select->where('u.userid in (?)', $options['userid']);
//    	}
//    	return $select;
//    }
}
?>